package com.rd.draw.controller;

import com.rd.animation.type.AnimationType;
import com.rd.animation.type.BaseAnimation;
import com.rd.animation.type.ColorAnimation;
import com.rd.animation.type.FillAnimation;
import com.rd.animation.type.ScaleAnimation;
import com.rd.draw.data.Indicator;
import com.rd.draw.data.Orientation;
import com.rd.draw.data.RtlMode;
import com.rd.utils.AttrUtils;
import com.rd.utils.DensityUtils;

import ohos.agp.components.AttrSet;
import ohos.agp.components.Component;
import ohos.agp.utils.Color;
import ohos.app.Context;

public class AttributeController {

    private static final int DEFAULT_IDLE_DURATION = 3000;

    private Indicator indicator;

    public AttributeController(Indicator indicator) {
        this.indicator = indicator;
    }

    private Context context;

    public void init(Context context, AttrSet attrs) {
        this.context = context;
        initCountAttribute(attrs);
        initColorAttribute(attrs);
        initAnimationAttribute(attrs);
        initSizeAttribute(attrs);
    }

    private void initCountAttribute(AttrSet attrSet) {
        int viewPagerId = AttrUtils.getIntFromAttr(attrSet, "piv_viewPager", Component.ID_DEFAULT);
        boolean autoVisibility = AttrUtils.getBooleanFromAttr(attrSet, "piv_autoVisibility", true);
        boolean dynamicCount = AttrUtils.getBooleanFromAttr(attrSet, "piv_dynamicCount", false);
        int count = AttrUtils.getIntFromAttr(attrSet, "piv_count", Indicator.COUNT_NONE);

        if (count == Indicator.COUNT_NONE) {
            count = Indicator.DEFAULT_COUNT;
        }
        int position = AttrUtils.getIntFromAttr(attrSet, "piv_select", 0);

        if (position < 0) {
            position = 0;
        } else if (count > 0 && position > count - 1) {
            position = count - 1;
        }

        indicator.setPageSliderId(viewPagerId);
        indicator.setAutoVisibility(autoVisibility);
        indicator.setDynamicCount(dynamicCount);
        indicator.setCount(count);

        indicator.setSelectedPosition(position);
        indicator.setSelectingPosition(position);
        indicator.setLastSelectedPosition(position);
    }

    private void initColorAttribute(AttrSet attrSet) {
        int unselectedColor =
                AttrUtils.getColorFromAttr(
                        attrSet, "piv_unselectedColor", Color.getIntColor(ColorAnimation.DEFAULT_UNSELECTED_COLOR));
        int selectedColor =
                AttrUtils.getColorFromAttr(
                        attrSet, "piv_selectedColor", Color.getIntColor(ColorAnimation.DEFAULT_SELECTED_COLOR));

        indicator.setUnselectedColor(unselectedColor);
        indicator.setSelectedColor(selectedColor);
    }

    private void initAnimationAttribute(AttrSet attrSet) {
        boolean interactiveAnimation = AttrUtils.getBooleanFromAttr(attrSet, "piv_interactiveAnimation", false);
        long animationDuration =
                AttrUtils.getLongFromAttr(attrSet, "piv_animationDuration", BaseAnimation.DEFAULT_ANIMATION_TIME);
        if (animationDuration < 0) {
            animationDuration = 0;
        }

        int animIndex = AttrUtils.getIntFromAttr(attrSet, "piv_animationType", AnimationType.NONE.ordinal());
        AnimationType animationType = getAnimationType(animIndex);

        int rtlIndex = AttrUtils.getIntFromAttr(attrSet, "piv_rtl_mode", RtlMode.Off.ordinal());
        RtlMode rtlMode = getRtlMode(rtlIndex);

        boolean fadeOnIdle = AttrUtils.getBooleanFromAttr(attrSet, "piv_fadeOnIdle", false);
        long idleDuration = AttrUtils.getLongFromAttr(attrSet, "piv_idleDuration", DEFAULT_IDLE_DURATION);

        indicator.setAnimationDuration(animationDuration);
        indicator.setInteractiveAnimation(interactiveAnimation);
        indicator.setAnimationType(animationType);
        indicator.setRtlMode(rtlMode);
        indicator.setFadeOnIdle(fadeOnIdle);
        indicator.setIdleDuration(idleDuration);
    }

    private void initSizeAttribute(AttrSet attrSet) {
        int orientationIndex = AttrUtils.getIntFromAttr(attrSet, "piv_orientation", Orientation.HORIZONTAL.ordinal());
        Orientation orientation;

        if (orientationIndex == 0) {
            orientation = Orientation.HORIZONTAL;
        } else {
            orientation = Orientation.VERTICAL;
        }

        int radius =
                AttrUtils.getDimensionFromAttr(
                        attrSet, "piv_radius", DensityUtils.vpToPx(Indicator.DEFAULT_RADIUS_DP, context));
        if (radius < 0) {
            radius = 0;
        }

        int padding =
                AttrUtils.getDimensionFromAttr(
                        attrSet, "piv_padding", DensityUtils.vpToPx(Indicator.DEFAULT_PADDING_DP, context));
        if (padding < 0) {
            padding = 0;
        }

        float scaleFactor = AttrUtils.getFloatFromAttr(attrSet, "piv_scaleFactor", ScaleAnimation.DEFAULT_SCALE_FACTOR);
        if (scaleFactor < ScaleAnimation.MIN_SCALE_FACTOR) {
            scaleFactor = ScaleAnimation.MIN_SCALE_FACTOR;

        } else if (scaleFactor > ScaleAnimation.MAX_SCALE_FACTOR) {
            scaleFactor = ScaleAnimation.MAX_SCALE_FACTOR;
        }

        int stroke =
                AttrUtils.getDimensionFromAttr(
                        attrSet, "piv_strokeWidth", DensityUtils.vpToPx(FillAnimation.DEFAULT_STROKE_DP, context));
        if (stroke > radius) {
            stroke = radius;
        }

        if (indicator.getAnimationType() != AnimationType.FILL) {
            stroke = 0;
        }

        indicator.setRadius(radius);
        indicator.setOrientation(orientation);
        indicator.setPadding(padding);
        indicator.setScaleFactor(scaleFactor);
        indicator.setStroke(stroke);
    }

    private AnimationType getAnimationType(int index) {
        switch (index) {
            case 0:
                return AnimationType.NONE;
            case 1:
                return AnimationType.COLOR;
            case 2:
                return AnimationType.SCALE;
            case 3:
                return AnimationType.WORM;
            case 4:
                return AnimationType.SLIDE;
            case 5:
                return AnimationType.FILL;
            case 6:
                return AnimationType.THIN_WORM;
            case 7:
                return AnimationType.DROP;
            case 8:
                return AnimationType.SWAP;
            case 9:
                return AnimationType.SCALE_DOWN;
        }

        return AnimationType.NONE;
    }

    private RtlMode getRtlMode(int index) {
        switch (index) {
            case 0:
                return RtlMode.On;
            case 1:
                return RtlMode.Off;
            case 2:
                return RtlMode.Auto;
        }

        return RtlMode.Auto;
    }
}
